/*
 * 文件名称:          JSONUtil.java
 * 版权所有@ 2016——2017 无锡聆音科技有限公司，保留所有权利
 * 时间:             2016年7月27日 下午9:21:11
 */

package com.lingyin.json;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.AfterFilter;
import com.alibaba.fastjson.serializer.BeforeFilter;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.lingyin.json.deserializer.PropertyNameMappingDeserialierFilter;
import com.lingyin.json.filter.PropertyEnableFilter;
import com.lingyin.json.filter.PropertyNameMappingFilter;
import com.lingyin.json.filter.PropertyValueFilter;
import com.lingyin.json.filter.PropertyValueMethodFilter;
import com.lingyin.json.serializer.EnumSerializer;

/**
 *   该类提供定义的json处理，对基本的json处理直接使用com.alibaba.fastjson.JSON类中
 *  的相应方法即可。
 * 
 * @项目        jsonlib
 * 
 * @作者:       关宏新
 * 
 * @日期:       2016年7月27日
 * 
 * @负责人:    关宏新
 * 
 * @负责小组:   聆音项目组
 * 
 */
public final class JSONUtil
{
    private PropertyNameMappingFilter pnmf;
    private PropertyEnableFilter pef;
    private PropertyValueFilter pvf;
    private PropertyValueMethodFilter pvmf;
    private PropertyNameMappingDeserialierFilter deserializerProcesser;
    private String dateFormat;
    private boolean enumFlag;
    
    /**
     * 禁止外部实例化该类
     */
    private JSONUtil()
    {
    }
    
    /**
     * 禁止外部实例化该类
     * @param enumFlag 枚举对象是否转换所有值，为true表示对枚举对象，序列化的时候，
     * 会把枚举对象的所有属性值都进行序列化，false的时候，仅仅序列化枚举对象的名字或序号。
     */
    private JSONUtil(boolean enumFlag)
    {
        this.enumFlag = enumFlag;        
    }    
    
    /**
     * @return 返回 dateFormat
     */
    public String getDateFormat()
    {
        return dateFormat;
    }

    /** 设置时间格式
     * @param dateFormat 设置 dateFormat
     */
    public void setDateFormat(String dateFormat)
    {
        this.dateFormat = dateFormat;        
    }

    /**
     * 
     * @param object 需要转换的对象
     * @return String 对象转换后的json字符串
     */
    public String toJSONString(Object object)
    {
        return toJSONString(object, false);
    }
    
    /**
     * 
     * @param object 需要转换的对象
     * @param circulFlag 是否检查循环引用；如果该值为false，则表示不检查循环引用，此时如果
     * 在给定的对象中存在循环引用，则会导致死循环转换最后导致堆栈溢出，另外在该状态下，对于同一个对象引用，会
     * 多次完成转换；如对象A，如果其内部有两个同类型的对象B，如果在需要转换该A对象的时候，
     * 其两个B对象的值是同一个的时候，在该标记为false的时，该两个B对象会转换两次，而如果该标记
     * 为true，则该转换后一个B对象完整转换一次，另外一个B对象会转换为引用的方式
     * @return String 对象转换后的json字符串
     */
    public String toJSONString(Object object, boolean circulFlag)
    {
        SerializeWriter out = new SerializeWriter();
        JSONSerializer serializer = enumFlag ? new EnumSerializer(out) : new JSONSerializer(out);
        try
        {
            serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
            serializer.config(SerializerFeature.DisableCircularReferenceDetect, !circulFlag);
            if (dateFormat != null)
            {
                serializer.setDateFormat(dateFormat);
            }
            else
            {
                serializer.setDateFormat(JSON.DEFFAULT_DATE_FORMAT);
            }
            setFilter(serializer, pnmf, pef, pvf, pvmf);
            
            serializer.write(object);
            return out.toString();
        }
        finally
        {
            cleanAllFilter(serializer);
            out.close();
        }
    }
    
    /**
     * Java对象转Json字符串。通过该方法可以把clazz类中的某个属性定义转换为其他属性名。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * sourcePropertyName设置为[a,b]，targetPropertyName设置为[testA, testB]，则转换结果json对象为：
     * {"testA":xxx,"testB":yyy}
     * @param clazz 需要转换的class。
     * @param sourcePropertyName 需要转换的原属性名集合
     * @param targetPropertyName 需要转换的新属性命名集合
     */
    public void addNameMapping(Class<?> clazz, String sourcePropertyName, String targetPropertyName)
    {
        if (pnmf == null)
        {
            pnmf = new PropertyNameMappingFilter(clazz, sourcePropertyName, targetPropertyName);
        }
        else
        {
            pnmf.addPropertyMapping(clazz, sourcePropertyName, targetPropertyName);
        }
        
    }
    
    /**
     * Java对象转Json字符串。通过该方法可以把clazz类中的某个属性定义转换为其他属性名。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * sourcePropertyName设置为[a,b]，targetPropertyName设置为[testA, testB]，则转换结果json对象为：
     * {"testA":xxx,"testB":yyy}
     * @param clazz 需要转换的class。
     * @param sourcePropertyName 需要转换的原属性名集合
     * @param targetPropertyName 需要转换的新属性命名集合
     */
    public void addNameMapping(Class<?> clazz, String[] sourcePropertyName, String[] targetPropertyName)
    {
        if (pnmf == null)
        {
            pnmf = new PropertyNameMappingFilter(clazz, sourcePropertyName, targetPropertyName);
        }
        else
        {
            pnmf.addPropertyMapping(clazz, sourcePropertyName, targetPropertyName);
        }
        
    }
    
    /**
     * 
     * Java对象转Json字符串。通过该方法可以只转换clazz类中的某个属性定义。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * propertyName设置为[a]，则转换结果json对象为：{"b":yyy}，即是该对象的a属性不需要转换。
     * @param clazz 需要转换的class，如果该值为null，则表示针对object的类进行转换。
     * @param propertyName 需要转换的原属性名
     */
    public void addPropertyExcludes(Class<?> clazz, String ... propertyName)
    {
        if (pef == null)
        {
            pef = new PropertyEnableFilter();
        }
        pef.setDisableProperty(clazz, propertyName);        
    }
    
    /**
     * Java对象转Json字符串。通过该方法可以只转换clazz类中的某个属性定义。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * propertyName设置为[a]，则转换结果json对象为：{"a":xxx}, 即是只需要转换a属性
     * @param clazz 需要转换的class，如果该值为null，则表示针对object的类进行转换。
     * @param propertyName 需要转换的原属性名
     */
    public void addPropertyInclude(Class<?> clazz, String ... propertyName)
    {
        if (pef == null)
        {
            pef = new PropertyEnableFilter();
        }
        pef.setEnableProperty(clazz, propertyName);
        
    }

    /**
     * 增加过滤器
     * @param filters 需要增加的过滤器集合
     */
    public void addFilter(JSONSerializer serializer, SerializeFilter...filters)
    {
        setFilter(serializer, filters);
    }
    
    /**
     * Java对象转Json字符串。通过该方法可以只转换clazz类中的某个属性定义。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, String b}, 直接转换为json对象为{"a":xxx,"b":"yyy"}，如果采用该方法
     * name设置为b，method方法为Integer类的valueOf方法，params参数此时为没有，
     * 则转换结果json对象为：{"a":xxx,"b":yyy}, 即是只需要转换b属性的值为int类型的值，而不是原始的string类型的值。
     * @param clazz 需要替换的类
     * @param name 需要替换类的属性
     * @param m 需要用什么静态方法获取替换的值，注意该方法目前只支持静态方法。
     * @param params 静态方法的参数，这些参数为固定参数，静态方法的最后一个参数为需要替换的原始值，
     * 通过该值，由静态方法获取需要替换的值。
     */
    public void addPropertyValueChange(Class<?> clazz, String name, Method m, Object ... params)
    {
        if (pvf == null)
        {
            pvf = new PropertyValueFilter();
        }
        pvf.addReplaceMethod(clazz, name, m, params);        
    }
    
    /**
     * Java对象转Json字符串。通过该方法可以只转换clazz类中的某个属性定义。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, String b}, 直接转换为json对象为{"a":xxx,"b":"y2yy"}，如果采用该方法
     * name设置为b，method方法为String对象的subString方法，params参数此时为2，
     * 则转换结果json对象为：{"a":xxx,"b":"2yy"}, 即是只需要转换b属性的值为通过其某个方法而获取的值，
     * 而不是原始的string类型的值。
     * @param clazz 需要替换的类
     * @param name 需要替换类的属性
     * @param m 需要用对象的什么方法获取替换的值。
     * @param params 方法的参数，这些参数为固定参数
     */
    public void addPropertyValueMethodChange(Class<?> clazz, String name, Method m, Object ... params)
    {
        if (pvmf == null)
        {
            pvmf = new PropertyValueMethodFilter();
        }
        pvmf.addReplaceMethod(clazz, name, m, params);
        
    }
    
    /**
     * json字符转换为对象，根据需要可以对json字串中的key值修改为对象中对应的属性名。
     * 如：如果json字串中有key值为abc的值，需要在转换为对象的时候，把该abc的值转换为
     * 对象T的changeAbc属性的值，这可以通过该方法进行处理，此时参数filterClass为T的class，
     * sourcePropertyname为abc，targetPropertyName为changeAbc即可。在使用该方法
     * 的时候需要保证对象T的class定义有setChangeAbc（）方法。
     * @param input 需要转换的json字符串
     * @param clazz 需要生成的对象
     * @param filterClass 需要转换时候过滤的对象类名
     * @param sourcePropertyName 需要转换的原属性名集合，该值是在json字串中的key值
     * @param targetPropertyName 需要转换的新属性命名集合，该值为filterClass的属性名
     * @return 转换后的对象
     */
    public void addParseObjectProperty(Class<?> filterClass, String[] sourcePropertyName,
        String[] targetPropertyName)
    {
        if (deserializerProcesser == null)
        {
            deserializerProcesser = new PropertyNameMappingDeserialierFilter();
        }
        deserializerProcesser.addPropertyMapping(filterClass, sourcePropertyName, targetPropertyName);
    }
    
    /**
     * 替换现有的属性转换器
     * @param desiralierFileter
     */
    public void setParseObjectProperty(PropertyNameMappingDeserialierFilter desiralierFileter)
    {
        deserializerProcesser = desiralierFileter;
    }
    
    /**
     * json字符转换为对象，该方法不同于静态方法parseObject(String, class)
     * 的是，在该方法中会应用用户自定义的属性转换及过滤,
     * 通过该方法可以定义转换的对象相关属性，如果需要定制
     * 转换对象的属性，需要设置PropertyNameMappingDeserialierFilter的相关值，
     * 如果进行标准的转换，不需要定制相关属性，可以直接使用静态方法parseObject(String, class)
     * @param input 需要转换的json字符串
     * @param clazz 需要生成的对象
     * @return
     */
    public <T> T parseObject(Type clazz, String input)
    {
        if (input == null)
        {
            return null;
        }
        ParserConfig config = ParserConfig.getGlobalInstance();
        int  featureValues = JSON.DEFAULT_PARSER_FEATURE;
        DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);
        if (deserializerProcesser != null)
        {
            parser.getExtraProcessors().add(deserializerProcesser);
        }
        
        T value = (T)parser.parseObject(clazz);

        parser.handleResovleTask(value);

        parser.getExtraProcessors().clear();
        parser.close();

        return (T)value;
    }
    
    /**
     * json字符转换为对象，通过该方法可以定义转换的对象相关属性，如果需要定制
     * 转换对象的属性，需要设置PropertyNameMappingDeserialierFilter的相关值，
     * 如果进行标准的转换，不需要定制相关属性，可以直接使用静态方法parseArray(class, String)
     * @param input 需要转换的json字符串
     * @param clazz 需要生成的对象
     * @return
     */
    public <T> List<T> parseArray(String input, Class<?> clazz)
    {
        if (input == null)
        {
            return null;
        }
        ParserConfig config = ParserConfig.getGlobalInstance();
        int  featureValues = JSON.DEFAULT_PARSER_FEATURE;
        DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);
        if (deserializerProcesser != null)
        {
            parser.getExtraProcessors().add(deserializerProcesser);
        }
        
        List<T> list;
        JSONLexer lexer = parser.getLexer();
        if (lexer.token() == JSONToken.NULL)
        {
            lexer.nextToken();
            list = null;
        }
        else
        {
            list = new ArrayList<T>();
            parser.parseArray(clazz, list);

            parser.handleResovleTask(list);
        }
        parser.getExtraProcessors().clear();
        parser.close();

        return list;
    }
    
    //################### 以下为静态方法的定义 ####################
    /**
     * 获取一个json转换器，该转换器获取后，在使用的时候是非线程安全的，
     * 所以外界在获取该转换器后，最好是在单独线程中使用，不可用于多线程环境。
     * 如果没有特殊的需求，最好使用该类中提供的静态方法。
     * 在获取该对象后，可以使用addNameMapping()，addPropertyExcludes()，
     * addPropertyInclude()等方法进行相关属性处理。
     * 在获取该对象后，通过对象的toJSONString(Object object)方法获取json字符串。
     */
    public static JSONUtil getJSONUtil()
    {
        JSONUtil json = new JSONUtil();        
        return json;
    }
    
    /**
     * 获取一个json转换器，该转换器获取后，在使用的时候是非线程安全的，
     * 所以外界在获取该转换器后，最好是在单独线程中使用，不可用于多线程环境。
     * 如果没有特殊的需求，最好使用该类中提供的静态方法。
     * 在获取该对象后，可以使用addNameMapping()，addPropertyExcludes()，
     * addPropertyInclude()等方法进行相关属性处理。
     * 在获取该对象后，通过对象的toJSONString(Object object)方法获取json字符串。
     * @param enumFlag 枚举对象是否转换所有值，为true表示对枚举对象，序列化的时候，
     * 会把枚举对象的所有属性值都进行序列化，false的时候，仅仅序列化枚举对象的名字或序号。
     */
    public static JSONUtil getJSONUtil(boolean enumFlag)
    {
        JSONUtil json = new JSONUtil(enumFlag);        
        return json;
    }
    
    /**
     * 
     * Java对象转Json字符串。通过该方法可以把clazz类中的某个属性定义转换为其他属性名。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * sourcePropertyName设置为[a,b]，targetPropertyName设置为[testA, testB]，则转换结果json对象为：
     * {"testA":xxx,"testB":yyy}
     * @param object Java对象
     * @param clazz 需要转换的class，如果该值为null，则表示针对object的类进行转换。
     * @param sourcePropertyName 需要转换的原属性名
     * @param targetPropertyName 需要转换的新属性命名
     * @return json格式字符串
     */
    public static final String toJSONStringByNameMapping(Object object, Class<?> clazz, String sourcePropertyName, String targetPropertyName)
    {
        if (clazz == null)
        {
            clazz = object.getClass();
        }
        SerializeFilter filter = new PropertyNameMappingFilter(clazz, sourcePropertyName, targetPropertyName);
        return toJSONString(object, new SerializeFilter[]{filter});
    }
    
    /**
     *Java对象转Json字符串。通过该方法可以把clazz类中的某个属性定义转换为其他属性名。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * sourcePropertyName设置为[a,b]，targetPropertyName设置为[testA, testB]，则转换结果json对象为：
     * {"testA":xxx,"testB":yyy}
     * 注意sourcePropertyName， targetPropertyName的长度必须一致。
     * @param object Java对象
     * @param clazz 需要转换的class，如果该值为null，则表示针对object的类进行转换。
     * @param sourcePropertyName 需要转换的原属性名集合
     * @param targetPropertyName 需要转换的新属性命名集合
     * @return json格式字符串
     */
    public static final String toJSONStringByNameMapping(Object object, Class<?> clazz, String[] sourcePropertyName,
            String[] targetPropertyName)
    {
        if (clazz == null)
        {
            clazz = object.getClass();
        }
        SerializeFilter filter = new PropertyNameMappingFilter(clazz, sourcePropertyName, targetPropertyName);
        return toJSONString(object, new SerializeFilter[]{filter});
    }
    
    /**
     * 
     * Java对象转Json字符串。通过该方法可以只转换clazz类中的某个属性定义。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * propertyName设置为[a]，则转换结果json对象为：{"a":xxx}, 即是只需要转换a属性
     * @param object Java对象
     * @param clazz 需要转换的class，如果该值为null，则表示针对object的类进行转换。
     * @param propertyName 需要转换的原属性名
     * @return json格式字符串
     */
    public static final String toJSONStringByPropertyInclude(Object object, Class<?> clazz, String ... propertyName)
    {
        if (clazz == null)
        {
            clazz = object.getClass();
        }
        SerializeFilter filter = new PropertyEnableFilter(clazz, propertyName);
        return toJSONString(object, new SerializeFilter[]{filter});
    }
    
    /**
     * Java对象转Json字符串。通过该方法可以只转换clazz类中的某个属性定义。
     * 该clazz类既可以是需要转换的对象的class定义，也可以是需要转换对象内部的某个属性值对象定义。
     * 如class Domain{int a, int b}, 直接转换为json对象为{"a":xxx,"b":yyy}，如果采用该方法
     * propertyName设置为[a]，则转换结果json对象为：{"b":yyy}，即是该对象的a属性不需要转换。
     * @param object Java对象
     * @param clazz 需要转换的class，如果该值为null，则表示针对object的类进行转换。
     * @param propertyName 需要转换的原属性名
     * @return json格式字符串
     */
    public static final String toJSONStringByPropertyExcludes(Object object, Class<?> clazz, String ... propertyName)
    {
        if (clazz == null)
        {
            clazz = object.getClass();
        }
        PropertyEnableFilter filter = new PropertyEnableFilter(clazz);
        filter.setDisableProperty(clazz, propertyName);
        return toJSONString(object, new SerializeFilter[]{filter});
    }
    
    /**
     * 多个filters的方式进行对象json转换。
     * @param object 需要转换的对象
     * @param  filters 对转换对象的相关过滤处理，如果不需要过滤任何属性，该值可为null
     * @param features 转换是需要处理的特性，如果采用默认的设置，该值可为null
     * @return String 对象转换后的json字符串
     */
    public static final String toJSONString(Object object, SerializeFilter[] filters, SerializerFeature...features)
    {
        SerializeWriter out = new SerializeWriter();
        try
        {
            JSONSerializer serializer = new JSONSerializer(out);
            if (features != null)
            {
                for (SerializerFeature feature : features)
                {
                    serializer.config(feature, true);
                }
            }
            serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
            setFilter(serializer, filters); 
            serializer.write(object);

            return out.toString();
        }
        finally
        {
            out.close();
        }
    }
    
    /**
     * 多个filters的方式进行对象json转换。
     * @param object 需要转换的对象
     * @param filters 对转换对象的相关过滤处理，如果不需要过滤任何属性，该值可为null
     * @param features 转换是需要处理的特性，如果采用默认的设置，该值可为null
     * @param enumFlag 枚举对象是否转换所有值，为true表示对枚举对象，序列化的时候，
     * 会把枚举对象的所有属性值都进行序列化，false的时候，仅仅序列化枚举对象的名字或序号。
     * @return String 对象转换后的json字符串
     */
    public static final String toJSONString(Object object, boolean enumFlag, SerializeFilter[] filters, SerializerFeature...features)
    {
        SerializeWriter out = new SerializeWriter();
        try
        {
            JSONSerializer serializer;
            if (enumFlag)
            {
                serializer = new EnumSerializer(out);
            }
            else
            {
                serializer = new JSONSerializer(out);
            }
            if (features != null)
            {
                for (SerializerFeature feature : features)
                {
                    serializer.config(feature, true);
                }
            }
            serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
            setFilter(serializer, filters); 
            serializer.write(object);

            return out.toString();
        }
        finally
        {
            out.close();
        }
    }    
    
    
        
    /*
     * 判断是否存储同样的过滤器实现
     */
    private static SerializeFilter hasFilter(List<SerializeFilter> filters, Class<?> clazz)
    {
        for(SerializeFilter temp : filters)
        {
            if (clazz.isInstance(temp))
            {
                return temp;
            }
        }
        return null;
    }
    
    /**
     * 增加过滤器
     * @param serializer json序列化对象
     * @param filters 需要增加的过滤器集合
     */
    private static void setFilter(JSONSerializer serializer, SerializeFilter...filters)
    {
        if (filters == null)
        {
            return;
        }
        for (SerializeFilter filter : filters)
        {
            setFilter(serializer, filter);
        }
    }

    /**
     * 增加过滤器
     * @param serializer json序列化对象
     * @param filter 需要增加的过滤器集合
     */
    private static void setFilter(JSONSerializer serializer, SerializeFilter filter)
    {
        if (filter != null)
        {
            // 一个过滤器可以实现多个接口，所以以下判断不需要加else。
            if (filter instanceof PropertyPreFilter)
            {
                serializer.getPropertyPreFilters().add((PropertyPreFilter)filter);
            }
            if (filter instanceof NameFilter)
            {
                serializer.getNameFilters().add((NameFilter)filter);
            }
            if (filter instanceof ValueFilter)
            {
                serializer.getValueFilters().add((ValueFilter)filter);
            }
            if (filter instanceof PropertyFilter)
            {
                serializer.getPropertyFilters().add((PropertyFilter)filter);
            }
            if (filter instanceof BeforeFilter)
            {
                serializer.getBeforeFilters().add((BeforeFilter)filter);
            }
            if (filter instanceof AfterFilter)
            {
                serializer.getAfterFilters().add((AfterFilter)filter);
            }
        }
    }
    
    /**
     * 删除序列化中的所有过滤器
     * @param serializer json序列化对象
     * @param filter 需要增加的过滤器集合
     */
    private static void cleanAllFilter(JSONSerializer serializer)
    {
        // 一个过滤器可以实现多个接口，所以以下判断不需要加else。
        serializer.getPropertyPreFilters().clear();
        serializer.getNameFilters().clear();
        serializer.getValueFilters().clear();
        serializer.getPropertyFilters().clear();
        serializer.getBeforeFilters().clear();
        serializer.getAfterFilters().clear();
    }
    
    /**
     * 删除序列化中的过滤器
     * @param serializer json序列化对象
     * @param filter 需要增加的过滤器集合
     */
    private static void cleanFilter(JSONSerializer serializer, SerializeFilter filter)
    {
        if (filter != null)
        {
            // 一个过滤器可以实现多个接口，所以以下判断不需要加else。
            if (filter instanceof PropertyPreFilter)
            {
                serializer.getPropertyPreFilters().remove(filter);
            }
            if (filter instanceof NameFilter)
            {
                serializer.getNameFilters().remove(filter);
            }
            if (filter instanceof ValueFilter)
            {
                serializer.getValueFilters().remove(filter);
            }
            if (filter instanceof PropertyFilter)
            {
                serializer.getPropertyFilters().remove(filter);
            }
            if (filter instanceof BeforeFilter)
            {
                serializer.getBeforeFilters().remove(filter);
            }
            if (filter instanceof AfterFilter)
            {
                serializer.getAfterFilters().remove(filter);
            }
        }
    }
        
    /**
     * json字符转换为对象，根据需要可以对json字串中的key值修改为对象中对应的属性名。
     * 如：如果json字串中有key值为abc的值，需要在转换为对象的时候，把该abc的值转换为
     * 对象T的changeAbc属性的值，这可以通过该方法进行处理，此时参数filterClass为T的class，
     * sourcePropertyname为abc，targetPropertyName为changeAbc即可。在使用该方法
     * 的时候需要保证对象T的class定义有setChangeAbc（）方法。
     * @param input 需要转换的json字符串
     * @param clazz 需要生成的对象
     * @param filterClass 需要转换时候过滤的对象类名
     * @param sourcePropertyName 需要转换的原属性名集合，该值是在json字串中的key值
     * @param targetPropertyName 需要转换的新属性命名集合，该值为filterClass的属性名
     * @return 转换后的对象
     */
    public static final <T>T parseObject(String input, Type clazz, Class<?> filterClass, String[] sourcePropertyName,
        String[] targetPropertyName)
    {
        if (input == null)
        {
            return null;
        }
        ParserConfig config = ParserConfig.getGlobalInstance();
        int  featureValues = JSON.DEFAULT_PARSER_FEATURE;
        DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);
        
        if (filterClass != null)
        {
            PropertyNameMappingDeserialierFilter ep = new PropertyNameMappingDeserialierFilter();
            ep.addPropertyMapping(filterClass, sourcePropertyName, targetPropertyName);
            parser.getExtraProcessors().add(ep);
        }
        
        T value = (T)parser.parseObject(clazz);

        parser.handleResovleTask(value);

        parser.close();

        return (T)value;
    }
    
    /**
     * 
     * json字符转换为对象列表，转换完成后为该对象的list列表，根据需要可以对json字串中的key值修改为对象中对应的属性名。
     * 如：如果json字串中有key值为abc的值，需要在转换为对象的时候，把该abc的值转换为
     * 对象T的changeAbc属性的值，这可以通过该方法进行处理，此时参数filterClass为T的class，
     * sourcePropertyname为abc，targetPropertyName为changeAbc即可。在使用该方法
     * 的时候需要保证对象T的class定义有setChangeAbc（）方法。
     * @param input 需要转换的json字符串
     * @param clazz 需要生成的对象
     * @param filterClass 需要转换时候过滤的对象类名
     * @param sourcePropertyName 需要转换的原属性名集合，该值是在json字串中的key值
     * @param targetPropertyName 需要转换的新属性命名集合，该值为filterClass的属性名
     * @return 转换后的对象列表
     */
    public static final <T> List<T> parseArray(String text, Class<T> clazz, Class<?> filterClass, String[] sourcePropertyName,
        String[] targetPropertyName)
    {
        if (text == null)
        {
            return null;
        }

        List<T> list;

        DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance());
        if (filterClass != null)
        {
            PropertyNameMappingDeserialierFilter ep = new PropertyNameMappingDeserialierFilter();
            ep.addPropertyMapping(filterClass, sourcePropertyName, targetPropertyName);
            parser.getExtraProcessors().add(ep);
        }
        
        JSONLexer lexer = parser.getLexer();
        if (lexer.token() == JSONToken.NULL)
        {
            lexer.nextToken();
            list = null;
        }
        else
        {
            list = new ArrayList<T>();
            parser.parseArray(clazz, list);

            parser.handleResovleTask(list);
        }

        parser.close();

        return list;
    }     
    
    /**
     * 通过json格式字串，生成class对象
     * @param text json字串
     * @param clazz 需要生成的class对象类定义
     * @return 返回对象
     */
    public static final <T> T parseObject(String text, Class<T> clazz)
    {
        return JSON.parseObject(text, clazz);
    }
    
    /**
     * 通过json格式字串，生成class对象的list
     * @param text json字串
     * @param clazz 需要生成的class对象类定义
     * @return 返回对象
     */
    public static final <T> List<T> parseArray(Class<T> clazz, String text)
    {
        return JSON.parseArray(text, clazz);
    }
    
    /**
     * 通过json格式字串，生成type指定类型的对象list，注意需要生成的list的
     * json字串中表示对象的个数必须和type指定的长度一致
     * @param text text json字串
     * @param types 返回的list类型。
     * @return
     */
    public static final List<Object> parseArray(String text, Type[] types) 
    {
        return JSON.parseArray(text, types);
    }
    
    /**
     * 返回默认对象转换处理，对于date类型，处理格式为:yyyy-MM-dd HH:mm:ss
     * @param object
     * @return
     */
    public static final String toNormalJSONString(Object object)
    {
        return JSON.toJSONString(object);
    }

    /**
     * 转换对象为json格式字串，其中如果有date类型的字段，则该日期格式
     * 转换为dateFormat指定的格式
     * @param object
     * @param dateFormat
     * @return
     */
    public static final String toJSONString(Object object, String dateFormat)
    {
        return JSON.toJSONStringWithDateFormat(object, dateFormat);
    }
    
}
